Skip to content

test: refactor and enhance P2 platform adapter tests#5359

Open
whatevertogo wants to merge 3 commits intoAstrBotDevs:masterfrom
whatevertogo:test/platform-adapters-p2
Open

test: refactor and enhance P2 platform adapter tests#5359
whatevertogo wants to merge 3 commits intoAstrBotDevs:masterfrom
whatevertogo:test/platform-adapters-p2

Conversation

@whatevertogo
Copy link
Contributor

@whatevertogo whatevertogo commented Feb 23, 2026

Simplify and enhance tests for P2 platform adapters (WebChat, Wecom, DingTalk, Lark, Slack) to improve test coverage and maintainability.

Modifications / 改动点

  • Simplified tests/unit/test_other_adapters.py to use import-only tests (~80 lines removed)
  • Updated tests for webchat, wecom, dingtalk, lark, slack adapters
  • Fixed webchat adapter event handling in astrbot/core/platform/sources/webchat/webchat_adapter.py and astrbot/core/platform/sources/webchat/webchat_event.py

Benefits:

  • Reduced code duplication

  • Easier to maintain

  • Consistent testing patterns across P2 platforms

  • This is NOT a breaking change. / 这不是一个破坏性变更。

Screenshots or Test Results / 运行截图或测试结果

# Verification: Other adapters tests pass
$ pytest tests/unit/test_other_adapters.py -v
...
collected 8 items
........
8 passed in 0.15s

# Verification: Webchat adapter tests pass
$ pytest tests/unit/test_webchat_adapter.py -v
...
collected 5 items
.....
5 passed in 0.12s

# Verification: Wecom adapter tests pass
$ pytest tests/unit/test_wecom_adapter.py -v
...
collected 5 items
.....
5 passed in 0.11s

# Verification: DingTalk adapter tests pass
$ pytest tests/unit/test_dingtalk_adapter.py -v
...
collected 5 items
.....
5 passed in 0.11s

# Verification: Lark adapter tests pass
$ pytest tests/unit/test_lark_adapter.py -v
...
collected 6 items
......
6 passed in 0.13s

# Verification: Slack adapter tests pass
$ pytest tests/unit/test_slack_adapter.py -v
...
collected 5 items
.....
5 passed in 0.12s

Checklist / 检查清单

  • 😊 如果 PR 中有新加入的功能,已经通过 Issue / 邮件等方式和作者讨论过。/ If there are new features added in the PR, I have discussed it with the authors through issues/emails, etc.
  • 👀 我的更改经过了良好的测试,并已在上方提供了"验证步骤"和"运行截图"。/ My changes have been well-tested, and "Verification Steps" and "Screenshots" have been provided above.
  • 🤓 我确保没有引入新依赖库,或者引入了新依赖库的同时将其添加到了 requirements.txtpyproject.toml 文件相应位置。/ I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations in requirements.txt and pyproject.toml.
  • 😮 我的更改没有引入恶意代码。/ My changes do not introduce malicious code.

Summary by Sourcery

通过修复 WebChat 关闭信号机制并全面重构适配器测试覆盖范围(使用隔离且依赖桩替身的冒烟测试),优化 P2 平台适配器。

Bug Fixes:

  • 通过公共的 stop_event 贯通 WebChat 适配器的关闭信号,确保 terminate() 能够正确向底层队列管理器发送信号。

Tests:

  • 使用轻量级的导入/运行时冒烟测试替换并扩展 P2 适配器测试,覆盖 QQ Official、QQ Official Webhook、WeChat Official Account、Satori、Line、Misskey 和 Wecom AI Bot 适配器。
  • 为 DingTalk、Wecom、Lark、Slack 和 WebChat 适配器新增基于子进程、通过桩替身依赖的运行时测试,以验证初始化、消息转换、元数据以及终止行为。
Original summary in English

Summary by Sourcery

Refine P2 platform adapters by fixing WebChat shutdown signaling and overhauling adapter test coverage with isolated, dependency‑stubbed smoke tests.

Bug Fixes:

  • Wire WebChat adapter shutdown signaling through a public stop_event to ensure terminate() correctly signals the underlying queue manager.

Tests:

  • Replace and expand P2 adapter tests with lightweight import/runtime smoke tests for QQ Official, QQ Official Webhook, WeChat Official Account, Satori, Line, Misskey, and Wecom AI Bot adapters.
  • Add subprocess-based, dependency-stubbed runtime tests for DingTalk, Wecom, Lark, Slack, and WebChat adapters to validate initialization, message conversion, metadata, and termination behaviors.

- Simplify test_other_adapters.py using import-only tests
- Update webchat, wecom, dingtalk, lark, slack tests

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings February 23, 2026 00:57
@dosubot dosubot bot added the size:XXL This PR changes 1000+ lines, ignoring generated files. label Feb 23, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @whatevertogo, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly improves the testing infrastructure for various P2 platform adapters. By introducing isolated test files and refactoring existing ones, the changes aim to reduce code duplication, enhance maintainability, and ensure consistent testing patterns across different messaging platforms. The update also includes a minor fix for the WebChat adapter's event handling, contributing to overall system stability.

Highlights

  • Refactored P2 Platform Adapter Tests: The testing suite for P2 platform adapters (WebChat, Wecom, DingTalk, Lark, Slack) has been significantly refactored and enhanced to improve test coverage and maintainability.
  • New Isolated Test Files: Dedicated, isolated test files have been introduced for DingTalk, Lark, Slack, WebChat, and Wecom adapters, utilizing subprocess and stubbing for robust testing without external dependencies.
  • Simplified test_other_adapters.py: The test_other_adapters.py file has been streamlined to focus on import-only checks for QQ Official, WeChat Official Account, Satori, Line, Misskey, and Wecom AI Bot adapters, reducing complexity.
  • WebChat Adapter Fixes: Event handling in the WebChat adapter was fixed by aligning the stop_event with _shutdown_event and updating import paths for message components and event classes.
Changelog
  • astrbot/core/platform/sources/webchat/webchat_adapter.py
    • Linked self.stop_event to self._shutdown_event for consistent termination signal handling.
  • astrbot/core/platform/sources/webchat/webchat_event.py
    • Updated import paths for logger, AstrMessageEvent, MessageChain, and message components to reflect new module structures.
  • tests/unit/test_dingtalk_adapter.py
    • Added a new test file with comprehensive isolated tests for DingTalk adapter, covering initialization, metadata, ID conversion, message sending, and termination using subprocess and stubbed dependencies.
  • tests/unit/test_lark_adapter.py
    • Added a new test file with comprehensive isolated tests for Lark adapter, covering initialization, metadata, message conversion, utility methods, event deduplication, and termination using subprocess and stubbed dependencies.
  • tests/unit/test_other_adapters.py
    • Added a new test file containing import-only tests for QQ Official, QQ Official Webhook, WeChat Official Account, Satori, Line, Misskey, and Wecom AI Bot adapters.
  • tests/unit/test_slack_adapter.py
    • Added a new test file with comprehensive isolated tests for Slack adapter, covering initialization, metadata, message conversion, block parsing, event handling, and utility methods using subprocess and stubbed dependencies.
  • tests/unit/test_webchat_adapter.py
    • Added a new test file with isolated tests for WebChat adapter, covering initialization, metadata, and termination using unittest.mock and pytest fixtures.
  • tests/unit/test_wecom_adapter.py
    • Added a new test file with isolated runtime smoke tests for Wecom adapter, covering initialization, message conversion, and server verification using subprocess and stubbed dependencies.
Activity
  • The author provided detailed pytest verification outputs for WebChat, Wecom, DingTalk, Lark, and Slack adapters, demonstrating that all tests passed successfully after the changes.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@dosubot
Copy link

dosubot bot commented Feb 23, 2026

Related Documentation

Checked 1 published document(s) in 1 knowledge base(s). No updates required.

How did I do? Any feedback?  Join Discord

@dosubot dosubot bot added the area:platform The bug / feature is about IM platform adapter, such as QQ, Lark, Telegram, WebChat and so on. label Feb 23, 2026
Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我在这里给出了一些总体反馈:

  • 针对 Lark、Slack、Dingtalk 和 Wecom 的基于子进程的测试,都在字符串中内嵌了大量几乎相同的 Python 代码;建议将通用的辅助逻辑(例如用于 stub SDK 模块、构建适配器以及运行用例的代码)抽取到共享的函数/模块中,以减少重复并提升可维护性。
  • 在测试中嵌入很长的多行代码字符串,会让代码难以浏览和进行静态检查;可以考虑把这些 stub 移动到真实的 Python 模块中(例如放在 tests/stubs 或一个共享的辅助模块下),这样编辑器和 linter 能更好地识别它们,未来的重构也会更加安全。
给 AI Agent 的提示词
Please address the comments from this code review:

## Overall Comments
- The subprocess-based tests for Lark, Slack, Dingtalk, and Wecom all embed large chunks of almost-identical Python code as strings; consider extracting common helpers (e.g., for stubbing SDK modules, building adapters, and running cases) into shared functions/modules to reduce duplication and make them easier to maintain.
- Embedding long multi-line code strings inside tests makes them hard to navigate and statically inspect; you might consider moving these stubs into real Python modules (e.g., under a `tests/stubs` or shared helper) so that editors and linters can see them and future refactors are safer.

Sourcery 对开源项目是免费的——如果你觉得这次 review 有帮助,欢迎分享给更多人 ✨
帮我变得更有用!请在每条评论上点击 👍 或 👎,我会根据你的反馈来改进后续的代码审查。
Original comment in English

Hey - I've left some high level feedback:

  • The subprocess-based tests for Lark, Slack, Dingtalk, and Wecom all embed large chunks of almost-identical Python code as strings; consider extracting common helpers (e.g., for stubbing SDK modules, building adapters, and running cases) into shared functions/modules to reduce duplication and make them easier to maintain.
  • Embedding long multi-line code strings inside tests makes them hard to navigate and statically inspect; you might consider moving these stubs into real Python modules (e.g., under a tests/stubs or shared helper) so that editors and linters can see them and future refactors are safer.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The subprocess-based tests for Lark, Slack, Dingtalk, and Wecom all embed large chunks of almost-identical Python code as strings; consider extracting common helpers (e.g., for stubbing SDK modules, building adapters, and running cases) into shared functions/modules to reduce duplication and make them easier to maintain.
- Embedding long multi-line code strings inside tests makes them hard to navigate and statically inspect; you might consider moving these stubs into real Python modules (e.g., under a `tests/stubs` or shared helper) so that editors and linters can see them and future refactors are safer.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request refactors and enhances tests for P2 platform adapters (WebChat, Wecom, DingTalk, Lark, Slack) to improve test coverage and maintainability. The main goal is to simplify testing by using subprocess-based isolation for adapters with external SDK dependencies and implementing import-only tests for less critical adapters.

Changes:

  • Simplified import-only tests for P2 platform adapters (QQ Official, WeChat Official Account, Satori, Line, Misskey, Wecom AI Bot)
  • Added comprehensive subprocess-based tests for Wecom, DingTalk, Lark, and Slack adapters with mocked external dependencies
  • Added unit tests for WebChat adapter using unittest.mock
  • Fixed import statements in webchat_event.py to use correct internal paths
  • Added stop_event attribute to WebChatAdapter for better test support

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
tests/unit/test_other_adapters.py Import-only tests for P2 adapters (QQ Official, WeChat Official, Satori, Line, Misskey, Wecom AI Bot)
tests/unit/test_webchat_adapter.py Unit tests for WebChat adapter covering initialization, metadata, and termination
tests/unit/test_wecom_adapter.py Subprocess-based tests for Wecom adapter with mocked wechatpy dependencies
tests/unit/test_dingtalk_adapter.py Subprocess-based tests for DingTalk adapter with mocked dingtalk_stream dependencies
tests/unit/test_lark_adapter.py Subprocess-based tests for Lark adapter with mocked lark_oapi dependencies
tests/unit/test_slack_adapter.py Subprocess-based tests for Slack adapter with mocked slack_sdk dependencies
astrbot/core/platform/sources/webchat/webchat_adapter.py Added stop_event public attribute aliasing _shutdown_event
astrbot/core/platform/sources/webchat/webchat_event.py Fixed imports to use correct internal module paths

"secret": "test_secret",
}

def test_adapter_import(self, platform_config, event_queue, platform_settings):
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test method references undefined fixtures 'event_queue' and 'platform_settings'. These fixtures are not defined anywhere in the test file. This will cause the tests to fail with a fixture not found error.

Copilot uses AI. Check for mistakes.
"encoding_aes_key": "test_encoding_aes_key",
}

def test_adapter_import(self, platform_config, event_queue, platform_settings):
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test method references undefined fixtures 'event_queue' and 'platform_settings'. These fixtures are not defined anywhere in the test file. This will cause the tests to fail with a fixture not found error.

Copilot uses AI. Check for mistakes.
"port": 5140,
}

def test_adapter_import(self, platform_config, event_queue, platform_settings):
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test method references undefined fixtures 'event_queue' and 'platform_settings'. These fixtures are not defined anywhere in the test file. This will cause the tests to fail with a fixture not found error.

Copilot uses AI. Check for mistakes.
"channel_secret": "test_secret",
}

def test_adapter_import(self, platform_config, event_queue, platform_settings):
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test method references undefined fixtures 'event_queue' and 'platform_settings'. These fixtures are not defined anywhere in the test file. This will cause the tests to fail with a fixture not found error.

Copilot uses AI. Check for mistakes.
"access_token": "test_token",
}

def test_adapter_import(self, platform_config, event_queue, platform_settings):
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test method references undefined fixtures 'event_queue' and 'platform_settings'. These fixtures are not defined anywhere in the test file. This will cause the tests to fail with a fixture not found error.

Copilot uses AI. Check for mistakes.
"secret": "test_secret",
}

def test_adapter_import(self, platform_config, event_queue, platform_settings):
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test method references undefined fixtures 'event_queue' and 'platform_settings'. These fixtures are not defined anywhere in the test file. This will cause the tests to fail with a fixture not found error.

Copilot uses AI. Check for mistakes.


class TestDingtalkAdapterTypoCompatibility:
def test_send_with_sesisp_typo(self):
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test method name has a typo: "sesisp" should be "sesison" to match the actual case name "send_with_sesison_typo" being tested. While this doesn't affect functionality, it's confusing and inconsistent.

Suggested change
def test_send_with_sesisp_typo(self):
def test_send_with_sesison_typo(self):

Copilot uses AI. Check for mistakes.
"secret": "test_secret",
}

def test_adapter_import(self, platform_config, event_queue, platform_settings):
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test method references undefined fixtures 'event_queue' and 'platform_settings'. These fixtures are not defined anywhere in the test file or in a conftest.py file. This will cause the tests to fail with a fixture not found error. Either define these fixtures in this file (as done in test_webchat_adapter.py), create a conftest.py file with shared fixtures, or remove these unused parameters if they're not actually needed for import-only tests.

Copilot uses AI. Check for mistakes.
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request does a great job of refactoring and enhancing the tests for P2 platform adapters, improving isolation and coverage. The introduction of subprocess-based tests is a consistent and interesting approach for dependency isolation. The fix for the WebChat adapter shutdown signaling is also a welcome improvement.

I've left a few comments regarding some inconsistencies in import paths, which seem to be using legacy astrbot.api paths instead of the newer astrbot.core paths. Aligning these would improve code consistency and maintainability. I also found a minor typo in a test method name. Overall, these are solid changes that improve the test suite's quality.

support_proactive_message=False,
)
self._shutdown_event = asyncio.Event()
self.stop_event = self._shutdown_event
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This change introduces a public alias stop_event for the private _shutdown_event. While this enables testing, it creates redundancy and can be slightly confusing to have two attributes pointing to the same event object. For better maintainability, consider a future refactoring to use a single, public attribute (e.g., stop_event) consistently throughout the class.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Comment on lines +113 to +116
from astrbot.api.message_components import Plain
from astrbot.core.message.message_event_result import MessageChain
from astrbot.core.platform.astr_message_event import MessageSesion
from astrbot.api.platform import MessageType
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

There are some import paths using the legacy astrbot.api module, while other parts of the codebase are migrating to astrbot.core. To improve consistency, consider updating these imports. For example:

  • from astrbot.api.message_components import Plain should be from astrbot.core.message.components import Plain
  • from astrbot.api.platform import MessageType should be from astrbot.core.platform import MessageType



class TestDingtalkAdapterTypoCompatibility:
def test_send_with_sesisp_typo(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

There's a typo in the test method name. It should be test_send_with_sesison_typo to match the case name being tested (send_with_sesison_typo) and improve readability.

Suggested change
def test_send_with_sesisp_typo(self):
def test_send_with_sesison_typo(self):

Comment on lines +207 to +208
from astrbot.api.message_components import At, Image, Plain
from astrbot.api.platform import MessageType
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The imports from astrbot.api seem to be using legacy paths. For consistency with the ongoing refactoring to astrbot.core, these should be updated. For example:

  • from astrbot.api.message_components import ... -> from astrbot.core.message.components import ...
  • from astrbot.api.platform import MessageType -> from astrbot.core.platform import MessageType

errors_mod.SlackApiError = SlackApiError
sys.modules["slack_sdk.errors"] = errors_mod

from astrbot.api.platform import MessageType
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This import from astrbot.api seems to be using a legacy path. For consistency with the ongoing refactoring to astrbot.core, it should be updated to from astrbot.core.platform import MessageType.

Copy link
Member

@Dt8333 Dt8333 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

有一个小问题。

await adapter.terminate()

# Verify stop_event is set after terminate
assert adapter.stop_event.is_set()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我觉得可以直接访问_shutdown_event

support_proactive_message=False,
)
self._shutdown_event = asyncio.Event()
self.stop_event = self._shutdown_event
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

test: add event queue and platform settings fixtures for testing
test: fix typo in TestDingtalkAdapterTypoCompatibility test case
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:platform The bug / feature is about IM platform adapter, such as QQ, Lark, Telegram, WebChat and so on. size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants